<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Generator 函数</title>
</head>
<body>
  
</body>
</html>

<script>
  function* f() {
    yield 1
    yield 'a'
    yield 4+5
    return 'shiguiwu'
  }


  //不会执行
  let a = f()

  //函数调用
  // console.log(a.next())
  // console.log(a.next())
  // console.log(a.next())
  // console.log(a.next())


  function* f1() {
    let a = yield 1+1//表达式的值 2 ， a的值需要传 4
    let b = yield a + 6 //表达式的值 a的值 4+6=10 b的值是传3
    let c = yield a + b //表达式的值 4 + 3 =7 c的值4
    return b + c // 表达式的值 7

  }

  a = f1();

  // next方法传值
  // console.log(a.next()) //2
  // console.log(a.next(4)) //10
  // console.log(a.next(3)) //7
  // console.log(a.next(4)) //7
  // console.log(a.next(4))  //NAN

  // for of 循环

  function* f2() {
    yield 2
    yield 3
    yield 4
    yield 5
    return 7
  }


  for(let v of f2()) {
    // console.log('for循环的值。。。。',v)
   // return语句返回的7，不包括在for...of循环之中。
  }

  //遍历对象
  function* f3(obj) {
    let propKeys = Reflect.ownKeys(obj)
    for( let o of propKeys) {
      yield [o,obj[o]]

    }
  }

  //遍历对象
  const shiguiwu = {name: 'shiguiwu', age: 18,'3rt': 99}

  for(let [k,v] of f3(shiguiwu)) {
    // console.log(`${k} : ${v}`)
  }

  //异常抛出，gen的throw和平时的throw是不一样的，一旦gen中产生异常，js引擎就会终止gen函数的执行
  function* f4() {
    try {
      yield ;
    } catch (error) {
      // console.log('内部捕获异常',error)

    }
  }

  a = f4()
  a.next()

  try {
    a.throw('a')
    a.throw('b')
  } catch (error) {
    // console.log('外部捕获异常',error)
    
  }

  // return 方法gen
  function* f5() {
    yield 1
    yield 100
    yield '22'
    return 777
  }


  a = f5()
  // console.log(a.next())
  // console.log(a.next())

  // 调用return方法，gen函数结束
  // console.log(a.return('bbbb'))

  // return  ...true
  // console.log(a.next())

  //yield*的问题，就是一个遍历器
  function* f6() {
    yield 6
    yield* 'shiguiwu'
  }

  a = f6()
  // console.log(a.next())
  // console.log(a.next())
  // console.log(a.next())
  // console.log(a.next()) 把数组展开了

  //gen 的this问题

  function* f7() {
    this.a = 'a'
    yield 1
  }

  f7.prototype.hello = function () {
    // console.log('hhi')
    
  }
  a = f7();
  a.hello()
  // console.log(a.a)

  //this
  function* f8() {
    this.a = 1
    yield this.b = 2
    yield this.c = 3

  }

  let obj = {} 

  a = f8.call(obj)

  // console.log(a.next())
  // console.log(a.next())
  // console.log(a.next())

  // console.log(obj.a)
  // console.log(obj.b)
  // console.log(obj.c)


  //统一只用一个对象

  a = f8.call(f8.prototype)

  // console.log(a.next())
  // console.log(a.next())
  // console.log(a.next())

  // console.log(a.a)
  // console.log(a.b)
  // console.log(a.c)

  //Generator 与状态机

  function* f9() {
    while(true) {
      console.log('Tock!')
      yield

      console.log('Tick!')
      yield
    }
  }

  a = f9()
  a.next()
  a.next()
  a.next()
  a.next()
  a.next()




  


</script>